#include "freetype-mgr.h"
#include "../utils/sha.h"
#include "../gfx/gfx-mgr.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "../../libs/stb/stb_image_write.h"

FreetypeMgr *FreetypeMgr::getInstance()
{
    static FreetypeMgr instance;
    return &instance;
}
void FreetypeMgr::init()
{
    this->_fontPath = "C:\\Windows\\Fonts\\simhei.ttf";
    // 初始化 FreeType
    if (FT_Init_FreeType(&this->_ft))
    {
        throw std::runtime_error("could not init FreeType Library");
    }
    // 加载字体

    if (FT_New_Face(this->_ft, this->_fontPath.c_str(), 0, &this->_face))
    {
        throw std::runtime_error("failed to load font");
    }
    std::cout << "face->num_glyphs: " << this->_face->num_glyphs << std::endl;

    this->crateFont("你好世界这是一段中文文本欢迎使用FreeType渲染", 30, 30);
}
std::string FreetypeMgr::crateFont(const std::string &str, uint32_t fontSize, uint32_t lineHeight)
{
    FT_Set_Pixel_Sizes(this->_face, 0, fontSize);
    std::vector<wchar_t> chars;
    std::wstring wstr = this->utf8_to_wstring(str);
    for (wchar_t c : wstr)
    {
        // 避免重复添加
        chars.push_back(c);
    }
    std::cout << "chars.size(): " << chars.size() << std::endl;
    // 将字符打包到纹理图集
    uint32_t rowHeight = 0;

    uint32_t x = 0;
    uint32_t y = 0;
    uint32_t atlasWidth = 0;
    uint32_t atlasHeight = 0;
    // 提前与计算宽高
    for (wchar_t c : chars)
    {
        if (FT_Load_Char(this->_face, c, FT_LOAD_RENDER))

        {
            continue;
        }
        FT_GlyphSlot glyph = this->_face->glyph;
        // 最大宽度
        uint32_t width = glyph->bitmap.width;
        atlasWidth += width + 1; // 加1像素间隔
        // 最大高度
        uint32_t height = glyph->bitmap.rows;
        atlasHeight = std::max(atlasHeight, height);
    }
    atlasHeight = std::max(atlasHeight, lineHeight);

    std::vector<uint8_t> atlasData(atlasWidth * atlasHeight * 4, 0);
    std::cout << "atlasWidth: " << atlasWidth << std::endl;
    std::cout << "atlasHeight: " << atlasHeight << std::endl;
    std::cout << "atlasData.size(): " << atlasData.size() << std::endl;

    for (wchar_t c : chars)
    {
        if (FT_Load_Char(this->_face, c, FT_LOAD_RENDER))

        {
            continue;
        }

        FT_GlyphSlot glyph = this->_face->glyph;
        uint32_t width = glyph->bitmap.width;
        uint32_t height = glyph->bitmap.rows;
        // 计算当前文字的x和y坐标的偏移量
        int offsetX = 0;
        int offsetY = (lineHeight - glyph->bitmap_top) / 2;

        // 复制字形数据到图集
        for (uint32_t i = 0; i < height; i++)
        {
            for (uint32_t j = 0; j < width; j++)
            {
                uint32_t atlasIndex = (y + offsetY + i) * atlasWidth + (offsetX + x + j);
                if (atlasIndex >= atlasData.size() / 4)
                {
                    continue;
                }
                if (atlasIndex < 0)
                {
                    continue;
                }
                // std::cout  << "atlasData.size(): " << atlasData.size()<< "   atlasIndex: " << atlasIndex*4 << std::endl;
                uint32_t glyphIndex = i * width + j;
                atlasData[atlasIndex * 4 + 0] = 255;
                atlasData[atlasIndex * 4 + 1] = 255;
                atlasData[atlasIndex * 4 + 2] = 255;
                atlasData[atlasIndex * 4 + 3] = glyph->bitmap.buffer[glyphIndex];
            }
        }
        x += width + 1; // 加1像素间隔
    }
    std::string textureUuid = SHA::hash(str) + "_" + std::to_string(fontSize);
    GfxMgr::getInstance()->createGfxTexture(textureUuid, atlasData.data(), atlasWidth, atlasHeight, 4, atlasWidth * atlasHeight * 4);
    this->saveAtlasAsPNG(textureUuid + ".png", atlasData, atlasWidth, atlasHeight);

    return textureUuid;
}

void FreetypeMgr::clearFont(std::string key)
{
    GfxMgr::getInstance()->destroyGfxTexture(key);

    // this->_fontMaps[key]--;
}

void FreetypeMgr::destroy()
{
    FT_Done_Face(this->_face);
    FT_Done_FreeType(this->_ft);
}
// this->saveAtlasAsPGM("font_atlas.ppm", atlasData, atlasWidth, atlasHeight);
// 保存单通道数据为PGM文件（更高效，文件更小）
void FreetypeMgr::saveAtlasAsPGM(const std::string &filename,
                                 const std::vector<uint8_t> &atlasData,
                                 int width, int height)
{
    if (atlasData.size() != width * height)
    {
        throw std::runtime_error("Atlas data size doesn't match dimensions");
    }

    std::ofstream file(filename, std::ios::binary);
    if (!file)
    {
        throw std::runtime_error("Failed to open file: " + filename);
    }

    // 写入PGM文件头
    file << "P5\n"
         << width << " " << height << "\n255\n";

    // 直接写入单通道数据
    file.write(reinterpret_cast<const char *>(atlasData.data()), atlasData.size());

    file.close();
}
void FreetypeMgr::saveAtlasAsPNG(const std::string &filename,
                                 const std::vector<uint8_t> &atlasData,
                                 int width, int height)
{
    // 由于 atlasData 是 int8_t（有符号字符），我们需要转换为 unsigned char
    std::vector<unsigned char> unsignedData(atlasData.size());
    for (size_t i = 0; i < atlasData.size(); ++i)
    {
        // 将有符号转换为无符号，保持相同的位模式
        unsignedData[i] = static_cast<unsigned char>(atlasData[i]);
    }

    // 保存为 PNG
    int result = stbi_write_png(
        filename.c_str(),    // 文件名
        width,               // 宽度
        height,              // 高度
        4,                   // 通道数 (RGBA)
        unsignedData.data(), // 数据指针
        width * 4            // 每行的字节数 (宽度 * 4通道)
    );

    if (result)
    {
        std::cout << "Successfully saved atlas to: " << filename << std::endl;
    }
    else
    {
        std::cerr << "Failed to save atlas to: " << filename << std::endl;
    }
}

// UTF-8 string 转 wstring
std::wstring FreetypeMgr::utf8_to_wstring(const std::string &str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(str);
}

// // wstring 转 UTF-8 string
// std::string wstring_to_utf8(const std::wstring& wstr) {
//     std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
//     return converter.to_bytes(wstr);
// }

// // 使用示例
// std::string utf8Text = "你好世界";
// std::wstring wideText = utf8_to_wstring(utf8Text);  // 转换为 L"你好世界"
//  // 设置字体大小
//     FT_Set_Pixel_Sizes(face, 0, this->_fontSize);
//     // 计算图集尺寸（这里以2048x2048为例，实际需要动态计算）
//     const uint32_t atlasWidth = 8192;
//     const uint32_t atlasHeight = 8192;
//     std::vector<uint8_t> atlasData(atlasWidth * atlasHeight, 0);
//     std::cout << "atlasWidth: " << atlasWidth << std::endl;
//     std::cout << "atlasHeight: " << atlasHeight << std::endl;

//     uint32_t x = 0;
//     uint32_t y = 0;
//     uint32_t rowHeight = 0;

//     // 加载常用汉字字符集（Unicode范围）
//     std::vector<wchar_t> chineseChars;
//     // for (wchar_t c = 0x4E00; c <= 0x9FFF; c++)
//     // { // 基本汉字区
//     //     chineseChars.push_back(c);
//     // }
//     // std::cout << "chineseChars1.size(): " << chineseChars.size() << std::endl;

//     // 加载ASCII字符
//     for (unsigned char c = 32; c < 128; c++)
//     {
//         // std::cout << "c: " << c << std::endl;

//         chineseChars.push_back(static_cast<wchar_t>(c));
//     }

//     for (wchar_t c = 0x4E00; c <= 0x9FA5; c++) {
//         chineseChars.push_back(c);
//     }
//     // std::wstring chineseText = L"你好世界这是一段中文文本欢迎使用FreeType渲染";
//     // for (wchar_t c : chineseText) {
//     //     // 避免重复添加
//     //     chineseChars.push_back(c);
//     // }

//     std::cout << "chineseChars2.size(): " << chineseChars.size() << std::endl;

//     // 将字符打包到纹理图集
//     for (wchar_t c : chineseChars)
//     {
//         if (FT_Load_Char(face, c, FT_LOAD_RENDER))
//         {
//             continue;
//         }
//         // std::cout << "face->num_glyphs:wchar_t " << std::endl;

//         FT_GlyphSlot glyph = face->glyph;
//         uint32_t width = glyph->bitmap.width;
//         uint32_t height = glyph->bitmap.rows;

//         // 检查是否需要换行
//         if (x + width >= atlasWidth)
//         {
//             x = 0;
//             y += rowHeight + 1; // 加1像素间隔
//             rowHeight = 0;
//         }

//         // 更新行高
//         rowHeight = std::max(rowHeight, height);

//         // 检查图集是否已满
//         if (y + height >= atlasHeight)
//         {
//             std::cout << "Warning: Font atlas is full!" << std::endl;
//             break;
//         }

//         // 复制字形数据到图集
//         for (uint32_t i = 0; i < height; i++)
//         {
//             for (uint32_t j = 0; j < width; j++)
//             {
//                 uint32_t atlasIndex = (y + i) * atlasWidth + (x + j);
//                 uint32_t glyphIndex = i * width + j;
//                 atlasData[atlasIndex] = glyph->bitmap.buffer[glyphIndex];
//             }
//         }
//         // 计算纹理坐标
//         Vec2 coords[4];
//         coords[0] = Vec2((float)x / atlasWidth, (float)(y + height) / atlasHeight);           // 左下
//         coords[1] = Vec2((float)(x + width) / atlasWidth, (float)(y + height) / atlasHeight); // 右下
//         coords[2] = Vec2((float)(x + width) / atlasWidth, (float)y / atlasHeight);            // 右上
//         coords[3] = Vec2((float)x / atlasWidth, (float)y / atlasHeight);                      // 左上

//         // 存储字符信息
//         Character character;
//         character.texCoords[0] = coords[0]; // 左下
//         character.texCoords[1] = coords[1]; // 右下
//         character.texCoords[2] = coords[2]; // 右上
//         character.texCoords[3] = coords[3]; // 左上
//         character.width = width;
//         character.height = height;
//         character.bearingX = glyph->bitmap_left;
//         character.bearingY = glyph->bitmap_top;
//         character.advance = static_cast<uint32_t>(glyph->advance.x);
//         this->_characters[c] = character;

//         x += width + 1; // 加1像素间隔
//     }

//     // // 创建 Vulkan 纹理
//     // createVulkanTexture(atlasData.data(), atlasWidth, atlasHeight);
//     // GfxMgr::getInstance()->createGfxTexture("font_atlas", atlasData.data(), atlasWidth, atlasHeight);
